`restrict' qualifer

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Vijay Kumar R Zanvar

    #1

    `restrict' qualifer

    Greetings,

    Are the following inferences of mine correct?

    1. #include <string.h>
    char *strcpy(char * restrict s1,
    const char * restrict s2);

    a. s1 != s2
    b. That means,

    char s[10] = "vijoeyz";
    (void) strcpy ( s, s ); /* though useless */

    is not allowed!

    2. #include <string.h>
    size_t strlen(const char *s);

    a. If there is only one parameter of type "pointer to T", for any type
    T, then the `restrict' qualifier need not be used.

    --
    Women and cats do as they please. Men and dogs
    should sit back, and learn to relax.


  • Richard Bos

    #2
    Re: `restrict' qualifer

    "Vijay Kumar R Zanvar" <vijaykumar.rz@ globaledgesoft. com> wrote:
    [color=blue]
    > Are the following inferences of mine correct?
    >
    > 1. #include <string.h>
    > char *strcpy(char * restrict s1,
    > const char * restrict s2);
    >
    > a. s1 != s2[/color]

    Yes.
    [color=blue]
    > b. That means,
    >
    > char s[10] = "vijoeyz";
    > (void) strcpy ( s, s ); /* though useless */
    >
    > is not allowed![/color]

    Yes. Note that the definition following this declaration in the Standard
    makes this explicit, even in C89:

    # If copying takes place between objects that overlap, the behavior
    # is undefined.
    [color=blue]
    > 2. #include <string.h>
    > size_t strlen(const char *s);
    >
    > a. If there is only one parameter of type "pointer to T", for any type
    > T, then the `restrict' qualifier need not be used.[/color]

    Yes.

    Richard

    Comment

    • Arthur J. O'Dwyer

      #3
      Re: `restrict' qualifer


      On Tue, 27 Apr 2004, Vijay Kumar R Zanvar wrote:[color=blue]
      >
      > Are the following inferences of mine correct?
      >
      > 1. #include <string.h>
      > char *strcpy(char * restrict s1,
      > const char * restrict s2);
      >
      > a. s1 != s2[/color]

      Not necessarily. Yes, if we're to assume that when you
      wrote 'strcpy' above you really meant 'strcpy', the function
      that copies the target of 's2' into the target of 's1'. But
      generally, no, we could have the pathological case

      int ptreq(const char * restrict s1, const char * restrict s2)
      {
      return (s1 == s2);
      }

      that would be perfectly conforming and unable to generate
      undefined behavior, no matter the values of 's1' and 's2'.
      [color=blue]
      > b. That means,
      >
      > char s[10] = "vijoeyz";
      > (void) strcpy ( s, s ); /* though useless */
      >
      > is not allowed![/color]

      Naturally. In the case of 'strcpy', the Standard explicitly
      rules this sort of thing out (see N869 7.21.2.3 #2). But
      again, in the general case, you *could* pass 's' twice to the
      'ptrcmp' function I defined above, because that function never
      tries to access the targets of those pointers --- only their
      values.
      [color=blue]
      > 2. #include <string.h>
      > size_t strlen(const char *s);
      >
      > a. If there is only one parameter of type "pointer to T", for any type
      > T, then the `restrict' qualifier need not be used.[/color]

      No. 'restrict' guarantees that the pointer will have a sort of
      a "lock" on its target for its entire lifetime. This means that
      the following program exhibits undefined behavior:

      char g[] = "hello world";
      void foo(const char * restrict s) {
      g[0] = 'J';
      puts(s);
      }
      int main(void) {
      foo(g);
      }

      because the target of 's' is modified through 'g' during the
      lifetime of 's'. I'm almost positive that by writing

      char ga[] = "hello world";
      char * restrict g = ga;

      at file scope, you would be "preventing " anyone's tampering with
      that string except through 'g', for the entire run of the program.
      Quotes around "preventing " because it's not something the compiler
      can catch; it just means anyone who tampers with that array invokes
      undefined behavior on himself.


      N.B.: You can't define

      char restrict ga[] = "hello world";

      by itself; 'restrict' can only be applied to pointers, according to
      N869. I don't see why it can't apply to array objects too; perhaps
      someone will enlighten me.

      -Arthur

      Comment

      • Martin Dickopp

        #4
        Re: `restrict' qualifer

        "Arthur J. O'Dwyer" <ajo@nospam.and rew.cmu.edu> writes:
        [color=blue]
        > N.B.: You can't define
        >
        > char restrict ga[] = "hello world";
        >
        > by itself; 'restrict' can only be applied to pointers, according to
        > N869. I don't see why it can't apply to array objects too; perhaps
        > someone will enlighten me.[/color]

        Two arrays can never alias, so there's no need to restrict qualify them,
        just like there is no need to const qualify them, as they can never be
        modified anyway. If you like, you can think of arrays as implictly
        const and restrict qualified.

        (In case it's not clear: By "array", I mean the array object itself, not
        its elements.)

        An array and a pointer can alias, but that situation can be expressed by
        (absence of) a restrict qualifier on the pointer.

        Martin


        --
        ,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
        / ,- ) http://www.zero-based.org/ ((_/)o o(\_))
        \ `-' `-'(. .)`-'
        `-. Debian, a variant of the GNU operating system. \_/

        Comment

        • Martin Dickopp

          #5
          Re: `restrict' qualifer

          "Vijay Kumar R Zanvar" <vijaykumar.rz@ globaledgesoft. com> writes:
          [color=blue]
          > Are the following inferences of mine correct?[/color]

          Yes.
          [color=blue]
          > 1. #include <string.h>
          > char *strcpy(char * restrict s1,
          > const char * restrict s2);
          >
          > a. s1 != s2
          > b. That means,
          >
          > char s[10] = "vijoeyz";
          > (void) strcpy ( s, s ); /* though useless */
          >
          > is not allowed![/color]

          Not only that, but the arguments may not even overlap.

          strcpy (s, s + 1);

          would likewise invoke undefined behavior.

          Martin


          --
          ,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
          / ,- ) http://www.zero-based.org/ ((_/)o o(\_))
          \ `-' `-'(. .)`-'
          `-. Debian, a variant of the GNU operating system. \_/

          Comment

          Working...